#include "..\stdafx.h"
#include "GWorld.h"

GWorld::GWorld(void)
	: m_miner(10)
{
	bool _map[9][12] = {						// y:
		{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },	// 0
		{ 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },	// 1
		{ 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 },	// 2
		{ 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 },	// 3
		{ 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0 },	// 4
		{ 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },	// 5
		{ 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 },	// 6
		{ 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1 },	// 7
		{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },	// 8
	// x: 0  1  2  3  4  5  6  7  8  9 10 11
	};
	m_map.SetMap(_map, 9);
}

GWorld::~GWorld(void)
{
}

time_t GWorld::GetGWorldTime()
{
	static time_t init_time = time(NULL) & ~(time_t)31;
	time_t now = time(NULL);

	time_t deff = now - init_time;

	deff *= 60; // +1 sec -> +1 min

	return init_time + deff;
}

HRESULT GWorld::CreateMapMesh(LPDIRECT3DDEVICE9 pd3ddev9)
{
	HRESULT hr = D3DXCreateBox(pd3ddev9, 240.0f, 5.0f, 180.0f, &m_mesh.m_pMesh, &m_mesh.m_pAdjacency);

	if (hr == S_OK)
	{
		m_mesh.m_pMesh->OptimizeInplace(
			D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
			( DWORD* )m_mesh.m_pAdjacency->GetBufferPointer(), NULL, NULL, NULL );
	}

	LPD3DXMESH pNewMesh = NULL;

	if ( SUCCEEDED( m_mesh.m_pMesh->CloneMeshFVF(m_mesh.m_pMesh->GetOptions(),
		(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1),
		pd3ddev9, &pNewMesh) ) )
	{
		m_mesh.m_pMesh->Release();
		m_mesh.m_pMesh = pNewMesh;

		_TRACE(_T("New Vertex FVF: 0x%.8X, have %u number of vertexes\n"), 
			m_mesh.m_pMesh->GetFVF(), 
			m_mesh.m_pMesh->GetNumVertices());

		LPVERTEXINFO_TEX1 pVertexInfo = NULL;

		// lock vertex buffer
		if ( SUCCEEDED( m_mesh.m_pMesh->LockVertexBuffer(D3DLOCK_DISCARD, (LPVOID*)&pVertexInfo) ) )
		{
			// set uv
			pVertexInfo[16].tu = 1.0f;
			pVertexInfo[16].tv = 0.0f;

			pVertexInfo[17].tu = 1.0f;
			pVertexInfo[17].tv = 3.0f / 4.0f;

			pVertexInfo[18].tu = 0.0f;
			pVertexInfo[18].tv = 3.0f / 4.0f;

			pVertexInfo[19].tu = 0.0f;
			pVertexInfo[19].tv = 0.0f;

			// unlock
			m_mesh.m_pMesh->UnlockVertexBuffer();
		}

		// create texture
		hr = D3DXCreateTextureFromFileEx(pd3ddev9, _T(".\\Resource\\map_base.jpg"),
			D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER, 
			D3DX_DEFAULT, 0, NULL, NULL, &m_mesh.m_pTextures);
	}

	// set materials
	m_mesh.m_pMaterials = new D3DXMATERIAL();
	ZeroMemory(m_mesh.m_pMaterials, sizeof(D3DXMATERIAL));
	
	m_mesh.m_pMaterials->MatD3D.Ambient.a = 1.0f;
	m_mesh.m_pMaterials->MatD3D.Ambient.r = 0.75f;
	m_mesh.m_pMaterials->MatD3D.Ambient.g = 0.75f;
	m_mesh.m_pMaterials->MatD3D.Ambient.b = 0.75f;

	m_mesh.m_pMaterials->MatD3D.Diffuse.a = 1.0f;
	m_mesh.m_pMaterials->MatD3D.Diffuse.r = 0.2f;
	m_mesh.m_pMaterials->MatD3D.Diffuse.g = 0.2f;
	m_mesh.m_pMaterials->MatD3D.Diffuse.b = 0.2f;

	//
	House::CreateMesh(pd3ddev9);

	//
	Mountain::CreateMesh(pd3ddev9);

	//
	Tree::CreateMesh(pd3ddev9);

	//
	Miner::CreateMesh(pd3ddev9);
	
	return hr;
}

D3DXVECTOR3 GWorld::GetAreaVector(int ax, int ay)
{
	return D3DXVECTOR3(-120.0f + 20.0f * ax + 10.0f, 2.5f, 90.0f - (20.0f * ay + 10.0f));
}

POINTU GWorld::GetArea(D3DXVECTOR3 vec)
{
	POINTU pos = {
		(ULONG)((vec.x + 120.0f) / 20.0f),
		(ULONG)((90.0f - vec.z) / 20.0f)
	};

	return pos;
}


void GWorld::Init()
{
	D3DXMATRIX matrix;
	D3DXVECTOR3 vector;
	
	vector = GetAreaVector(2, 3);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[0].Init(matrix);

	vector = GetAreaVector(3, 3);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[1].Init(matrix);

	vector = GetAreaVector(5, 3);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[2].Init(matrix);

	vector = GetAreaVector(6, 3);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[3].Init(matrix);

	vector = GetAreaVector(2, 4);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[4].Init(matrix);

	vector = GetAreaVector(3, 4);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[5].Init(matrix);

	vector = GetAreaVector(5, 4);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[6].Init(matrix);

	vector = GetAreaVector(6, 4);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[7].Init(matrix);

	vector = GetAreaVector(2, 6);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[8].Init(matrix);

	vector = GetAreaVector(3, 6);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[9].Init(matrix);

	vector = GetAreaVector(5, 6);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[10].Init(matrix);

	vector = GetAreaVector(6, 6);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[11].Init(matrix);

	vector = GetAreaVector(2, 7);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[12].Init(matrix);

	vector = GetAreaVector(3, 7);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[13].Init(matrix);

	vector = GetAreaVector(5, 7);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[14].Init(matrix);

	vector = GetAreaVector(6, 7);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[15].Init(matrix);

	vector = GetAreaVector(8, 4);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[16].Init(matrix);

	vector = GetAreaVector(8, 4);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[17].Init(matrix);

	vector = GetAreaVector(8, 5);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[18].Init(matrix);

	vector = GetAreaVector(8, 6);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[19].Init(matrix);

	vector = GetAreaVector(8, 7);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[20].Init(matrix);

	vector = GetAreaVector(9, 7);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[21].Init(matrix);

	vector = GetAreaVector(10, 7);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[22].Init(matrix);

	vector = GetAreaVector(11, 7);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_houses[23].Init(matrix);

	////////////////////////////////////////////////////////////
	// Mountains
	for (int i = 0; i < 12; i++)
	{
		vector = GetAreaVector(i, 0);
		D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
		m_mountains[i].Init(matrix, i * 0.25f + 0.5f);
	}
	
	for (int i = 0; i < 4; i++)
	{
		vector = GetAreaVector(8 + i, 1);
		D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
		m_mountains[12 + i].Init(matrix, i * 0.25f + 2.25f);
	}

	for (int i = 0; i < 3; i++)
	{
		vector = GetAreaVector(9 + i, 2);
		D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
		m_mountains[16 + i].Init(matrix, i * 0.25f + 2.25f);
	}

	for (int i = 0; i < 2; i++)
	{
		vector = GetAreaVector(10 + i, 3);
		D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
		m_mountains[19 + i].Init(matrix, i * 0.25f + 2.25f);
	}

	for (int i = 0; i < 2; i++)
	{
		vector = GetAreaVector(10 + i, 4);
		D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
		m_mountains[21 + i].Init(matrix, i * 0.25f + 2.0f);
	}

	vector = GetAreaVector(11, 5);
	D3DXMatrixTranslation(&matrix, vector.x, vector.y, vector.z);
	m_mountains[23].Init(matrix, 2.0f);


	////////////////////////////////////////////////////////////
	// Miner
	m_miner.SetPos(GetAreaVector(11, 8));
}

HRESULT GWorld::Draw(LPDIRECT3DDEVICE9 pd3ddev9)
{
	pd3ddev9->SetTransform(D3DTS_WORLD, &m_world);
	m_mesh.Draw(pd3ddev9);

	for (int i = 0; i < MAX_HOUSE ; i++)
		m_houses[i].Draw(pd3ddev9);

	for (int i = 0; i < MAX_MOUNTAIN ; i++)
		m_mountains[i].Draw(pd3ddev9);

	m_miner.Update(timeGetTime() / 1000.0f);
	m_miner.Draw(pd3ddev9);

	return S_OK;
}

POINTU GWorld::GetPoint(Locations location) const
{
	POINTU pos = { ~0U, ~0U };
	switch(location)
	{
	case Shack:
		pos.x = 11U;
		pos.y = 7U;
		return pos;
	case GoldMine:
		pos.x = 5U;
		pos.y = 0U;
		return pos;
	case Bank:
		pos.x = 3U;
		pos.y = 7U;
		return pos;
	case Bar:
		pos.x = 3U;
		pos.y = 4U;
		return pos;
	default:
		return pos;
	}
}

GWorld* pWorld = NULL;